#include "sActionHandlerEditText.h"
#include "sComponentInstance.h"
#include "sComponentRectInstance.h"
#include "sGUI.h"

namespace sgui
{
namespace inst
{
	
const float sActionHandlerEditText::BLINK_TIME = 400.f;
    
bool sActionHandlerEditText::OnEvent(const obs::sEvent& event)
{
    switch (event.getID())
    {
		case obs::EVID_KEY_CHAR:
		{
            CAST_EVENT(m_ev, sKeyboardCharEvent);

			std::wstring source_str = m_editText->getText();
            std::wstring source_str_1 = source_str.substr(0, m_cursorPosition.m_char);
			std::wstring source_str_2 = source_str.substr(m_cursorPosition.m_char);

			std::wstringstream release_strm;
			release_strm << source_str_1;
			release_strm << m_ev.m_char;
			release_strm << source_str_2;
			m_editText->setText(release_strm.str());

			m_cursorPosition.m_char++;

			return true;
		}
		case obs::EVID_KEY_PRESS:
		{
            CAST_EVENT(m_ev, sKeyboardPressEvent);

			switch (m_ev.m_button)
			{
				case obs::sKeyboardEvent::KEY_BACKSPACE:
				{
					if (m_cursorPosition.m_char > 0)
					{
						std::wstring source_str = m_editText->getText();
						std::wstring source_str_1 = source_str.substr(0, m_cursorPosition.m_char - 1);
						std::wstring source_str_2 = source_str.substr(m_cursorPosition.m_char);

						std::wstringstream release_strm;
						release_strm << source_str_1;
						release_strm << source_str_2;
						m_editText->setText(release_strm.str());

						m_cursorPosition.m_char--;
						return true;
					}
				}
				case obs::sKeyboardEvent::KEY_LEFT:
				{
					if (m_cursorPosition.m_char > 0)
					{
						m_cursorPosition.m_char--;
					}
					return true;
				}
				case obs::sKeyboardEvent::KEY_RIGHT:
				{
					if (m_cursorPosition.m_char < m_editText->getText().size())
					{
						m_cursorPosition.m_char++;
					}
					return true;
				}
			}

			return false;
		}
        case obs::EVID_MOUSE_PRESS:
        {
            CAST_EVENT(m_ev, sMousePressEvent);


            if (getActiveRect().pointIn(m_ev.m_position))
			{
                m_cursorPosition = m_editText->getPositionAt(m_ev.m_position - m_edit->getRect().getPosition());
                m_editText->getCursorPosition(m_cursorPosition, m_cursorPos, m_cursorHeight);

				getInstance()->getGui().getEngine().textBeginRead();
				return true;
			}
			else
			{
				getInstance()->getGui().getEngine().textEndRead();
				release(&m_ev);
				return false;
			}
        }
    }
    return false;
}
	
bool sActionHandlerEditText::update(double dt)
{
	m_timer += dt;

	if (m_timer > BLINK_TIME)
	{
		m_timer = 0;
	}

	return false;
}

void sActionHandlerEditText::draw(engine::sDrawStack& stack) const
{
	if (m_timer < BLINK_TIME / 2)
	{
        stack.getGui().getEngine().drawRect(
            math::sRectf(
                m_cursorPos + m_edit->getRect().getPosition() + m_editText->getRect().getPosition(), 
                math::sPointf(1, 13)), 
			0x00FFFFFF + ((int)(((float)m_timer / BLINK_TIME * 2) * 0xFF) << 24), false);
	}
}

sActionHandlerEditText::sActionHandlerEditText(sComponentInstance* instance, sComponentRectInstance *caller) :
    sActionHandler(instance, caller),
	m_timer(0)
{
    instance->setState(CS_ACTIVE);

	m_edit = static_cast<sComponentInstanceEdit*>(instance);
	m_editText = static_cast<sComponentRectEditableText*>(caller);
}
    
sActionHandlerEditText::~sActionHandlerEditText()
{
    getInstance()->setState(CS_NORMAL);
}

};
};